home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcl
/
sptmbr11.lha
/
clx
/
sockcl.lisp
< prev
next >
Wrap
Lisp/Scheme
|
1992-04-27
|
5KB
|
172 lines
;;; -*- Mode: LISP; Syntax: Common-lisp; Package: XLIB; Base: 10; Lowercase: Yes -*-
;;;; Server Connection for kcl and ibcl
;;; Copyright (C) 1987, 1989 Massachussetts Institute of Technology
;;;
;;; Permission is granted to any individual or institution to use, copy,
;;; modify, and distribute this software, provided that this complete
;;; copyright and permission notice is maintained, intact, in all copies and
;;; supporting documentation.
;;;
;;; Massachussetts Institute of Technology provides this software "as is"
;;; without express or implied warranty.
;;;
;;; Adapted from code by Roman Budzianowski - Project Athena/MIT
;;; make-two-way-stream is probably not a reasonable thing to do.
;;; A close on a two way stream probably does not close the substreams.
;;; I presume an :io will not work (maybe because it uses 1 buffer?).
;;; There should be some fast io (writes and reads...).
;;; Compile this file with compile-file.
;;; Load it with (si:faslink "sockcl.o" "socket.o -lc")
(in-package :xlib)
#+akcl
(clines "#define AKCL
")
;;; The cmpinclude.h file does not have this type definition from
;;; <kcldistribution>/h/object.h. We include it here so the
;;; compile-file will work without figuring out where the distribution
;;; directory is located.
;;;
(CLINES "
enum smmode { /* stream mode */
smm_input, /* input */
smm_output, /* output */
smm_io, /* input-output */
smm_probe, /* probe */
smm_synonym, /* synonym */
smm_broadcast, /* broadcast */
smm_concatenated, /* concatenated */
smm_two_way, /* two way */
smm_echo, /* echo */
smm_string_input, /* string input */
smm_string_output, /* string output */
smm_user_defined /* for user defined */
};
")
#-akcl
(CLINES "
struct stream {
short t, m;
FILE *sm_fp; /* file pointer */
object sm_object0; /* some object */
object sm_object1; /* some object */
int sm_int0; /* some int */
int sm_int1; /* some int */
short sm_mode; /* stream mode */
/* of enum smmode */
};
")
;;;; Connect to the server.
;;; A lisp string is not a reasonable type for C, so copy the characters
;;; out and then call connect_to_server routine defined in socket.o
(CLINES "
int
konnect_to_server(host,display)
object host; /* host name */
int display; /* display number */
{
int fd; /* file descriptor */
int i;
char hname[BUFSIZ];
FILE *fout, *fin;
if (host->st.st_fillp > BUFSIZ - 1)
too_long_file_name(host);
for (i = 0; i < host->st.st_fillp; i++)
hname[i] = host->st.st_self[i];
hname[i] = '\\0'; /* doubled backslash for lisp */
fd = connect_to_server(hname,display);
return(fd);
}
")
(defentry konnect-to-server (object int) (int "konnect_to_server"))
;;;; Make a one-way stream from a file descriptor.
(CLINES "
object
konnect_stream(host,fd,flag,elem)
object host; /* not really used */
int fd; /* file descriptor */
int flag; /* 0 input, 1 output */
object elem; /* 'string-char */
{
struct stream *stream;
char *mode; /* file open mode */
FILE *fp; /* file pointer */
enum smmode smm; /* lisp mode (a short) */
vs_mark;
switch(flag){
case 0:
smm = smm_input;
mode = \"r\";
break;
case 1:
smm = smm_output;
mode = \"w\";
break;
default:
FEerror(\"konnect_stream : wrong mode\");
}
fp = fdopen(fd,mode);
if (fp == NULL) {
stream = Cnil;
vs_push(stream);
} else {
stream = alloc_object(t_stream);
stream->sm_mode = (short)smm;
stream->sm_fp = fp;
stream->sm_object0 = elem;
stream->sm_object1 = host;
stream->sm_int0 = stream->sm_int1 = 0;
#ifdef AKCL
stream->sm_buffer = 0;
stream->sm_buffer = alloc_contblock(BUFSIZ);
setbuf(fp, stream->sm_buffer);
#else
vs_push(stream);
setbuf(fp, alloc_contblock(BUFSIZ));
#endif
}
vs_reset;
return(stream);
}
")
(defentry konnect-stream (object int int object) (object "konnect_stream"))
;;;; Open an X stream
(defun open-socket-stream (host display)
(when (not (and (typep host 'string) ; sanity check the arguments
(typep display 'fixnum)))
(error "Host ~s or display ~s are bad." host display))
(let ((fd (konnect-to-server host display))) ; get a file discriptor
(if (< fd 0)
NIL
(let ((stream-in (konnect-stream host fd 0 'string-char)) ; input
(stream-out (konnect-stream host fd 1 'string-char))) ; output
(if (or (null stream-in) (null stream-out))
(error "Could not make i/o streams for fd ~d." fd))
(make-two-way-stream stream-in stream-out))
)))